package com.zmn.mcc.admin.controller.staff;

import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.GlobalDict;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.logger.LoggerUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.office.ExcelUtil;
import com.zmn.common.utils.office.excel.ExportExcel;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.business.interfaces.staff.StaffBService;
import com.zmn.mcc.cache.StaffCache;
import com.zmn.mcc.cas.web.StaffAdminService;
import com.zmn.mcc.common.constant.StaffConsts;
import com.zmn.mcc.common.dictionary.StaffDict;
import com.zmn.mcc.common.dto.staff.EngineerBasicInfoDRO;
import com.zmn.mcc.model.entity.role.McRoleQuery;
import com.zmn.mcc.model.entity.staff.McStaff;
import com.zmn.mcc.model.entity.staff.McStaffQuery;
import com.zmn.mcc.model.vo.McStaffExportExcelVO;
import com.zmn.mcc.model.vo.McStaffVO;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

/**
 * @author heguanghua
 * @since 2020/04/15 10:54
 */
@Controller
@RequestMapping("/staff/")
public class StaffListController extends StaffBaseController {

    @Resource
    private StaffCache staffCache;

    @Resource
    private StaffBService staffBService;

    // 工程师或者劳务派遣或则劳务外包前缀
    private final static String RE_PREFIX = "re";

    /**
     * 员工列表
     */
    @RequestMapping(value = "list")
    public String list(HttpServletRequest request,
                       @ModelAttribute McStaffQuery query,
                       Model model) {

        String keyword = request.getParameter("keyword");

        // 账号为数字的时候查询bug修复
        //query.setStaffName(keyword);

        List<Date> lastLoginTimeRang = DateUtil.parseStandardDateRang(query.getLastLoginTimeRang());
        if (lastLoginTimeRang.size() > 0) {
            query.setLastLoginTimeBegin(lastLoginTimeRang.get(0));
        }
        if (lastLoginTimeRang.size() > 1) {
            query.setLastLoginTimeEnd(lastLoginTimeRang.get(1));
        }

        List<Date> entryTimeRange = DateUtil.parseStandardDateRang(query.getEntryTimeRange());
        if (entryTimeRange.size() > 0) {
            query.setEntryTimeStart(entryTimeRange.get(0));
        }
        if (entryTimeRange.size() > 1) {
            query.setEntryTimeEnd(entryTimeRange.get(1));
        }

        List<Date> becomeFormalTimeRange = DateUtil.parseStandardDateRang(query.getBecomeFormalTimeRange());
        if (becomeFormalTimeRange.size() > 0) {
            query.setBecomeFormalTimeStart(becomeFormalTimeRange.get(0));
        }
        if (becomeFormalTimeRange.size() > 1) {
            query.setBecomeFormalTimeEnd(becomeFormalTimeRange.get(1));
        }

        // 员工是否拥有"系统全局角色"
        Integer staffId = getStaffId();
        boolean isGlobalAdmin = staffBService.isGlobalAdmin(staffId);
        if (!isGlobalAdmin) {
            McStaff staff = staffService.findByKey(staffId);
            query.setPlat(staff.getPlat());
            query.setOrgTwoId(staff.getOrgTwoId());
            query.setOrgThrId(staff.getOrgThrId());
            query.setDeptOneId(staff.getDeptOneId());
            query.setDeptTwoId(staff.getDeptTwoId());
            query.setDeptThrId(staff.getDeptThrId());
        }

        List<McStaffVO> items = staffService.listPageInfoByQuery(query);

        model.addAttribute("items", items);
        model.addAttribute("vo", query);

        model.addAttribute("keyword", keyword);
        model.addAttribute("yesno", GlobalDict.getYesOrNoList());
        model.addAttribute("staffStatuses", StaffDict.getStatusList());
        model.addAttribute("statuses", GlobalDict.getStatusList(false));
        model.addAttribute("roleTypeList", StaffDict.getRoleTypeList());

        return "staff/list";
    }

    /**
     * 员工详情
     */
    @RequestMapping("detail")
    public String detail(HttpServletRequest request,
                         @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                         Model model) {

        McStaff obj = !NumberUtil.isNullOrZero(staffId) ? staffService.findByKey(staffId) : new McStaff();
        if (NumberUtil.isNullOrZero(obj.getWhitelist())) {
            obj.setWhitelist(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getPermitSelf())) {
            obj.setPermitSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitOrgSelf())) {
            obj.setDpermitOrgSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitAreaSelf())) {
            obj.setDpermitAreaSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitChannelSelf())) {
            obj.setDpermitChannelSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitDeptSelf())) {
            obj.setDpermitDeptSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitCubeSelf())) {
            obj.setDpermitCubeSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitMeasureSelf())) {
            obj.setDpermitMeasureSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getDpermitProductSelf())) {
            obj.setDpermitProductSelf(GlobalDict.YESNO_NO);
        }
        if (NumberUtil.isNullOrZero(obj.getType())) {
            obj.setType(StaffConsts.STAFF_ROLE_MASTER_TYPE);
        }
        if (StringUtil.isBlank(obj.getStaffName())) {
            // 获取生成的员工账号
            obj.setStaffName(getAutoStaffName());
        }

        model.addAttribute("obj", obj);

        model.addAttribute("orgOnes", organizeService.listByParentId(GlobalConsts.TOP_ID, GlobalDict.STATUS_NULL));
        model.addAttribute("orgTwos", !NumberUtil.isNullOrZero(obj.getPlat()) ? organizeService.listByParentId(obj.getPlat().intValue()) : new ArrayList<>());
        model.addAttribute("orgThrs", !NumberUtil.isNullOrZero(obj.getOrgTwoId()) ? organizeService.listByParentId(obj.getPlat().intValue()) : new ArrayList<>());

        model.addAttribute("deptOnes", deptService.listByParentId(GlobalConsts.TOP_ID, GlobalDict.STATUS_NULL));
        model.addAttribute("deptTwos", !NumberUtil.isNullOrZero(obj.getDeptOneId()) ? deptService.listByParentId(obj.getDeptOneId()) : new ArrayList<>());
        model.addAttribute("deptThrs", !NumberUtil.isNullOrZero(obj.getDeptTwoId()) ? deptService.listByParentId(obj.getDeptTwoId()) : new ArrayList<>());

        model.addAttribute("types", StaffDict.getRoleTypeList());

        model.addAttribute("periods", StaffDict.getProbationPeriodTypeList());
        model.addAttribute("positions", StaffDict.getGradesTypeList());
        model.addAttribute("staffStatusList", StaffDict.getStatusList());
        model.addAttribute("roleTypes", StaffDict.getRoleTypeList());
        model.addAttribute("sexTypes", StaffDict.getSexTypeList());
        model.addAttribute("flag", 1);
        model.addAttribute("desensitizedMobile", StringUtil.formatHideMobile(obj.getMobile()));
        model.addAttribute("roles", roleService.listByQuery(new McRoleQuery()));
        return "staff/detail";
    }

    /**
     * 设置临时密码
     */
    @RequestMapping("detail/pwd")
    public String detailPwd(HttpServletRequest request,
                            @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                            Model model) {

        McStaff obj = !NumberUtil.isNullOrZero(staffId) ? staffService.findByKey(staffId) : new McStaff();

        model.addAttribute("obj", obj);

        return "staff/detail_pwd";
    }

    /**
     * 设置不限IP日期
     */
    @RequestMapping("detail/opendate")
    public String detailOpendate(HttpServletRequest request,
                                 @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                                 Model model) {

        McStaff obj = !NumberUtil.isNullOrZero(staffId) ? staffService.findByKey(staffId) : new McStaff();

        String dateRange = staffCache.getOpenDate(staffId);

        model.addAttribute("obj", obj);
        model.addAttribute("dateRange", StringUtil.isNotBlank(dateRange) ? dateRange : "");

        return "staff/detail_opendate";
    }

    /**
     * 设置不限IP日期
     */
    @RequestMapping("batch/opendate")
    public String batchOpendate(HttpServletRequest request,
                                @RequestParam(value = "ids", defaultValue = "") String ids,
                                Model model) {
        McStaff obj = staffService.findByKey(getStaffId());
        model.addAttribute("obj", obj);
        model.addAttribute("staffIds", ids);
        model.addAttribute("dateRange", "");
        return "staff/batch_opendate";
    }

    /**
     * 设置IP白名单
     */
    @RequestMapping("detail/whitelist")
    public String detailWhitelist(HttpServletRequest request,
                                  @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                                  Model model) {

        McStaff obj = !NumberUtil.isNullOrZero(staffId) ? staffService.findByKey(staffId) : new McStaff();
        if (NumberUtil.isNullOrZero(obj.getWhitelist())) {
            obj.setWhitelist(GlobalDict.YESNO_NO);
        }

        model.addAttribute("obj", obj);
        model.addAttribute("yesno", GlobalDict.getYesOrNoList());

        return "staff/detail_whitelist";
    }

    /**
     * 绑定工程师
     */
    @RequestMapping("detail/master")
    public String detailMaster(HttpServletRequest request,
                               @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                               Model model) {

        McStaff obj = !NumberUtil.isNullOrZero(staffId) ? staffService.findByKey(staffId) : new McStaff();

        model.addAttribute("obj", obj);

        return "staff/detail_master";
    }

    /**
     * 绑定账户
     */
    @RequestMapping("bind/master")
    public String bindMaster(HttpServletRequest request,
                             @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                             Model model) {
        EngineerBasicInfoDRO engineer = staffBService.getEngineerByStaffId(staffId);
        model.addAttribute("obj", engineer);
        return "staff/bind_master";
    }

    /**
     * 绑定账户
     */
    @RequestMapping("bind/bindingStaffAndMaster")
    @ResponseBody
    public ResponseDTO bindingStaffAndMaster(HttpServletRequest request,
                                             @RequestParam(value = "staffId", defaultValue = "0") Integer staffId,
                                             @RequestParam(value = "engineerId", defaultValue = "0") Integer engineerId,
                                             @RequestParam(value = "engineerRole", defaultValue = "0") Integer engineerRole,
                                             Model model) {
        Boolean engineer = staffBService.bindingStaffAndMaster(engineerRole, staffId, engineerId, getLoginStaff().getRealName());
        if (engineer) {
            return ResponseDTO.success();
        } else {
            return ResponseDTO.fail("绑定失败");
        }
    }

    /**
     * 描述: 下载员工绩效EXCEL表
     *
     * @author linfeng
     * @since 2020/06/04
     **/
    @RequestMapping("outPutTemplate")
    public void outPutTemplate(HttpServletResponse response) {
        try {
            response.setContentType("application/binary;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("content-Type", "application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("员工绩效模板.xlsx", "UTF-8"));
            InputStream inputStream = new FileInputStream(new File(ResourceUtils.getURL("classpath:").getPath() + "template/员工绩效模板.xlsx"));
            XSSFWorkbook workbook = new XSSFWorkbook(inputStream);
            OutputStream out;
            out = response.getOutputStream();
            workbook.write(out);
            out.flush();
            out.close();
        } catch (Exception e) {
            LoggerUtil.error(this.getClass(), "导出报表出错" + e.getMessage(), e);
        }
    }

    /**
     * 描述: 下载错误名单
     *
     * @author linfeng
     * @since 2020/05/25
     **/
    @RequestMapping(value = "outPutErrorData")
    public void outPutErrorData(HttpServletResponse response, @RequestBody List<List<String>> errorData) {

        List<String> title = Arrays.asList("工号", "姓名", "考核开始时间", "考核结束时间", "考核指标", "得分", "备注");
        ArrayList<List> lists = Lists.newArrayList();
        lists.add(title);

        for (List<String> row : errorData) {
            lists.add(row);
        }

        try {
            String name = "错误名单.xlsx";
            name = new String(name.getBytes(), "ISO8859-1");
            ExcelUtil.export(response, lists, name, "sheet");
        } catch (Exception e) {
            LoggerUtil.error(this.getClass(), "导出报表出错" + e.getMessage(), e);
        }
    }

    @RequestMapping("toimportperformanceexcel")
    public ModelAndView toimportPerformanceExcel() {
        ModelAndView mav = new ModelAndView("staff/toimportperformanceexcel");

        return mav;
    }

    /**
     * 描述: 导入员工绩效excel
     *
     * @param file 传入的文件对象
     * @return com.zmn.common.dto2.ResponseDTO<java.lang.String>
     * @author linfeng
     * @since 2020/05/26
     **/
    @RequestMapping(value = "importExcel")
    @ResponseBody
    public ResponseDTO importExcel(@RequestParam(value = "file") MultipartFile file) {
        if (Objects.isNull(file)) {
            logger.error("导入员工绩效excel失败，文件对象为空");
            return com.zmn.common.dto2.ResponseDTO.fail("导入excel失败，文件对象为空");
        }

        try {
            return staffBService.importExcel(file.getInputStream(), getStaffName());
        } catch (IOException e) {
            logger.error("读取员工绩效excel文件失败！", e);
            return com.zmn.common.dto2.ResponseDTO.fail("读取员工绩效excel文件失败");
        }
    }

    @RequestMapping(value = "judgeExportExcel")
    @ResponseBody
    public ResponseDTO judgeExportExcel() {
        Integer pageSize = StaffAdminService.currentStaff().getExportLimit();
        if (NumberUtil.isNullOrZero(pageSize)) {
            return ResponseDTO.fail("您没有配置导出数量，无法导出！");
        }

        return ResponseDTO.success(pageSize, GlobalConsts.SUCCESS_MSG);
    }

    @RequestMapping(value = "exportExcel")
    public void exportExcel(HttpServletResponse response, McStaffQuery query) throws Exception {
        Integer pageSize = StaffAdminService.currentStaff().getExportLimit();
        query.setPageSize(pageSize);

        // 员工是否拥有"系统全局角色"
        Integer staffId = getStaffId();
        boolean isGlobalAdmin = staffBService.isGlobalAdmin(staffId);
        if (!isGlobalAdmin) {
            McStaff staff = staffService.findByKey(staffId);
            query.setPlat(staff.getPlat());
            query.setOrgTwoId(staff.getOrgTwoId());
            query.setOrgThrId(staff.getOrgThrId());
            query.setDeptOneId(staff.getDeptOneId());
            query.setDeptTwoId(staff.getDeptTwoId());
            query.setDeptThrId(staff.getDeptThrId());
        }

        ExportExcel<McStaffExportExcelVO> excel = staffBService.exportExcel(query);
        excel.exportExcel(response, "人员管理列表");
    }

    /**
     * 描述: 获取自动生成的员工账号
     *
     * @return java.lang.String
     * @author guoqiao
     * @since 2021/3/1 16:15
     */
    private String getAutoStaffName() {

        try {
            String maxStaffName = staffService.findMaxStaffName();
            if (StringUtil.isBlank(maxStaffName)) {
                return RE_PREFIX + String.format("%" + 6 + "s", GlobalConsts.NO).replace(' ', '0');
            }
            String tmp = maxStaffName.replace(RE_PREFIX, "");
            int i = Integer.parseInt(tmp) + 1;
            return RE_PREFIX + String.format("%" + 6 + "s", i).replace(' ', '0');
        } catch (NumberFormatException e) {
            logger.error("工程师账号生成异常,原因:{}", e.getMessage(), e);
            throw new RuntimeException("工程师账号生成异常");
        }
    }
}
